#include "HWarnings.h"
#include "HXD1.h"

unsigned int HWarnings::ymr = 0u;

HWarnings::HWarnings()
{
	assert(++ymr == 1u);
	to_be_located = 0u;
}

// Add a warning with message `msg`
size_t HWarnings::add_warning(const char *msg)
{
	size_t idx = _warnings.size();
	_warnings.resize(idx + 1ul);
	_warnings.at(idx).msg = msg;
	// use zero to represent unknown position
	_warnings.at(idx).line_no = 0ul;
	return idx;
}

// Locate all warnings from `to_be_located`
size_t HWarnings::locate(antlr4::ParserRuleContext *ctx)
{
	size_t n = _warnings.size(), l_ymr = 0ul;
	for (; to_be_located < n; ++to_be_located)
	{
		_warnings.at(to_be_located).text = ctx->getText();
		if (ctx->start != nullptr)
		{
			_warnings.at(to_be_located).line_no = ctx->start->getLine();
			_warnings.at(to_be_located).pos_in_line = ctx->start->getCharPositionInLine();
		}
		++l_ymr;
	}
	return l_ymr;
}

// Show all warnings
void HWarnings::show() const
{
	for (auto & w : _warnings)
	{
		std::cout << BOLD_MAGENTA "warning:" COLOR_RESET " line ";
		if (w.line_no > 0ul)
			std::cout << w.line_no << ':' << w.pos_in_line;
		else
			std::cout << "*:*";
		std::cout << ": '" << w.text << "' " << w.msg << std::endl;
	}
}

HWarnings::~HWarnings()
{
	assert(--ymr == 0u);
	if (to_be_located != _warnings.size())
		std::cout << BOLD_MAGENTA "warning:" COLOR_RESET
			" not all warnings are located" << std::endl;
}